package com.smartstate.ems.schedul;


import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONArray;
import com.smartstate.ems.entity.AirCompressor;
import com.smartstate.ems.entity.Equipment;
import com.smartstate.ems.mapper.EquipmentMapper;
import com.smartstate.ems.mapper.ObjMoudelMapper;
import com.smartstate.ems.vo.DehumidifierVO;
import com.smartstate.ems.vo.ObjMoudelNameVo;
import com.smartstate.ems.vo.ResultVO;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.Nullable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Component
public class DataRealTime {

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private EquipmentMapper equipmentMapper;

    @Resource
    private ObjMoudelMapper objMoudelMapper;

    private Map<String, Object> objectMap = null;

    private Map<String, Object> deviceIdMap = null;

    //        设置小数点不足两位添0格式
    private DecimalFormat decimalFormat = new DecimalFormat("0.0");

    @Scheduled(cron = "* * * * * ?")
    public void send() {
        if (WebSocketCopy.webSocketMap.size() > 0 && WebSocketCopy.dataDTO != null){
            //查询空间结构中的所有objId
            objectMap = objMoudelMapper.queryAllObjId("1");
            //查询所有设备对应空间建模的所有objId
            deviceIdMap = objMoudelMapper.queryAllDeviceIdFitAllObjId("1");
            HashMap<String, List<AirCompressor>> hashMap = new HashMap<>();
            List<Equipment> equipmentList = equipmentMapper.selectEquipmentByTypes(WebSocketCopy.dataDTO);
            Map<Integer, List<Equipment>> collect = equipmentList.stream().collect(Collectors.groupingBy(Equipment::getType));
            for (Integer key : collect.keySet()) {
                String keyStr = String.valueOf(key);
                if (keyStr.equals(WebSocketCopy.dataDTO.getNitrogenType())) {
//                制氮机
                    hashMap.put("nitrogen", queryNitrogenData(collect.get(key)));
                } else if (keyStr.equals(WebSocketCopy.dataDTO.getScrewVacuumType())) {
//                螺杆真空
                    hashMap.put("screwVacuum", queryScrewVacuumData(collect.get(key)));
                } else if (keyStr.equals(WebSocketCopy.dataDTO.getDustRemovalType())) {
//                除尘
                    hashMap.put("dustRemoval", selectAspirating(collect.get(key)));
                } else if (keyStr.equals(WebSocketCopy.dataDTO.getAirCompressorType())) {
//                空压机
                    hashMap.put("airCompressor", selectAirCompressor(collect.get(key)));
                }
            }
            WebSocketCopy.sendInfo(ResultVO.ok(hashMap));
            HashMap<String, List<DehumidifierVO>> dehumidifierHashMap = new HashMap<>();
            dehumidifierHashMap.put("dehumidifier", dehumidifierTree(Integer.valueOf(WebSocketCopy.dataDTO.getDehumidifierType())));
            WebSocketCopy.sendInfo(ResultVO.ok(dehumidifierHashMap));
        }
    }

    /**
     * 查询螺杆真空
     *
     * @return
     */
    public List<AirCompressor> queryScrewVacuumData(List<Equipment> equipment) {
        if (equipment == null && equipment.size() == 0) {
            return null;
        }

        List<AirCompressor> airCompressors = new ArrayList<>(16);
        equipment.forEach(e -> {
            AirCompressor airCompressor = new AirCompressor();
            Map entries = redisTemplate.opsForHash().entries(e.getDeviceId());
            String outPressure = null;
            String inPressure = null;
            String exitTemperature = null;
            if (entries == null || entries.size() == 0) {
                outPressure = "0.0";
                inPressure = "0.0";
                exitTemperature = "0.0";
            } else {
                outPressure = entries.get("outPressure") == null ? "0.0" : entries.get("outPressure").toString();
                inPressure = entries.get("inPressure") == null ? "0.0" : entries.get("inPressure").toString();
                exitTemperature = entries.get("exitTemperature") == null ? "0.0" : entries.get("exitTemperature").toString();
            }

//            保留一位小数,位数不够添0
            outPressure = decimalFormat.format(new BigDecimal(outPressure).setScale(1,RoundingMode.DOWN).floatValue());
            inPressure = decimalFormat.format(new BigDecimal(inPressure).setScale(1,RoundingMode.DOWN).floatValue());
            exitTemperature = decimalFormat.format(new BigDecimal(exitTemperature).setScale(1,RoundingMode.DOWN).floatValue());
            //进行名称拼接
            String objId  = String.valueOf(((Map) deviceIdMap.get(e.getDeviceId())).get("objId"));
            Map<String, Object> map = (Map) objectMap.get(objId);
            String objIdName = "";
            while(true){
                objIdName = objIdName == "" ? map.get("name") + objIdName : map.get("name") + "-" + objIdName;
                if ("0".equals(map.get("parentId"))){
                    break;
                }
                map = (Map) objectMap.get(map.get("parentId"));
            }
            airCompressor.setObjName(objIdName);
            airCompressor.setOutPressure(outPressure);
            airCompressor.setInPressure(inPressure);
            airCompressor.setExitTemperature(exitTemperature);
            airCompressor.setDeviceId(e.getDeviceId());
            airCompressor.setName(e.getName());
            airCompressor.setDateTime(DateUtil.format(new DateTime(), "yyyy-MM-dd HH:mm:ss"));
            airCompressor.setAlias(e.getAlias());
            airCompressors.add(airCompressor);
        });
        return airCompressors;
    }

    /**
     * 查询制氮机
     *
     * @return
     */
    public List<AirCompressor> queryNitrogenData(List<Equipment> equipment) {
        if (equipment == null && equipment.size() == 0) {
            return null;
        }
        List<AirCompressor> airCompressors = new ArrayList<>(16);
        equipment.forEach(e -> {
            AirCompressor airCompressor = new AirCompressor();
            Map entries = redisTemplate.opsForHash().entries(e.getDeviceId());
            String instantPressure = null;
            String purity = null;
            String temperature = null;
            if (entries == null || entries.size() == 0) {
                instantPressure = "0.0";
                purity = "0.0";
                temperature = "0.0";
            } else {
                instantPressure = entries.get("instantPressure") == null ? "0.0" : entries.get("instantPressure").toString();
                purity = entries.get("purity") == null ? "0.0" : entries.get("purity").toString();
                temperature = entries.get("temperature") == null ? "0.0" : entries.get("temperature").toString();
            }
//            保留一位小数,位数不够添0
            instantPressure = decimalFormat.format(new BigDecimal(instantPressure).setScale(1,RoundingMode.DOWN).floatValue());
            purity = decimalFormat.format(new BigDecimal(purity).setScale(1,RoundingMode.DOWN).floatValue());
            temperature = decimalFormat.format(new BigDecimal(temperature).setScale(1,RoundingMode.DOWN).floatValue());
            //进行名称拼接
            String objId  = String.valueOf(((Map) deviceIdMap.get(e.getDeviceId())).get("objId"));
            Map<String, Object> map = (Map) objectMap.get(objId);
            String objIdName = "";
            while(true){
                objIdName = objIdName == "" ? map.get("name") + objIdName : map.get("name") + "-" + objIdName;
                if ("0".equals(map.get("parentId"))){
                    break;
                }
                map = (Map) objectMap.get(map.get("parentId"));
            }
            airCompressor.setObjName(objIdName);
            airCompressor.setTemperature(temperature);
            airCompressor.setPurity(purity);
            airCompressor.setInstantPresure(instantPressure);
            airCompressor.setDeviceId(e.getDeviceId());
            airCompressor.setName(e.getName());
            airCompressor.setDateTime(DateUtil.format(new DateTime(), "yyyy-MM-dd HH:mm:ss"));
            airCompressor.setAlias(e.getAlias());
            airCompressors.add(airCompressor);
        });
        return airCompressors;
    }

    /**
     * 查空压机
     */
    public List<AirCompressor> selectAirCompressor(List<Equipment> equipment) {
        if (equipment == null && equipment.size() == 0) {
            return null;
        }
        List<AirCompressor> airCompressors = new ArrayList<>(16);
        equipment.forEach(e -> {
            AirCompressor airCompressor = new AirCompressor();
            Map entries = redisTemplate.opsForHash().entries(e.getDeviceId());
            if (entries != null && entries.size() > 0) {
                if (entries.get("pressure") != null && !"".equals(entries.get("pressure"))) {
                    airCompressor.setPressure(decimalFormat.format(new BigDecimal(entries.get("pressure").toString()).setScale(1, RoundingMode.DOWN).floatValue()));
                } else {
                    airCompressor.setPressure("0.0");
                }
                if (entries.get("dewPoint") != null && !"".equals(entries.get("dewPoint"))) {
                    airCompressor.setDewPoint(decimalFormat.format(new BigDecimal(entries.get("dewPoint").toString()).setScale(1, RoundingMode.DOWN).floatValue()));
                } else {
                    airCompressor.setDewPoint("0.0");
                }
                if (entries.get("temperature") != null && !"".equals(entries.get("temperature"))) {
                    airCompressor.setTemperature(decimalFormat.format(new BigDecimal(entries.get("temperature").toString()).setScale(1, RoundingMode.DOWN).floatValue()));
                } else {
                    airCompressor.setTemperature("0.0");
                }
            } else {
                airCompressor.setPressure("0.0");
                airCompressor.setDewPoint("0.0");
                airCompressor.setTemperature("0.0");
            }
            //进行名称拼接
            String objId  = String.valueOf(((Map) deviceIdMap.get(e.getDeviceId())).get("objId"));
            Map<String, Object> map = (Map) objectMap.get(objId);
            String objIdName = "";
            while(true){
                objIdName = objIdName == "" ? map.get("name") + objIdName : map.get("name") + "-" + objIdName;
                if ("0".equals(map.get("parentId"))){
                    break;
                }
                map = (Map) objectMap.get(map.get("parentId"));
            }
            airCompressor.setObjName(objIdName);
            airCompressor.setDeviceId(e.getDeviceId());
            airCompressor.setName(e.getName());
            airCompressor.setAlias(e.getAlias());
            airCompressor.setDateTime(DateUtil.format(new DateTime(), "yyyy-MM-dd HH:mm:ss"));
            airCompressors.add(airCompressor);
        });
        return airCompressors;
    }


    /**
     * 查除尘数据
     */
    public List<AirCompressor> selectAspirating(List<Equipment> equipment) {
        if (equipment == null && equipment.size() == 0) {
            return null;
        }
        List<AirCompressor> airCompressors = new ArrayList<>(16);
        equipment.forEach(e -> {
            AirCompressor airCompressor = new AirCompressor();
            Map entries = redisTemplate.opsForHash().entries(e.getDeviceId());
            if (entries != null && entries.size() > 0) {
                if (entries.get("neGaTive") != null && !"".equals(entries.get("neGaTive"))) {
                    airCompressor.setNeGaTive(decimalFormat.format(new BigDecimal(entries.get("neGaTive").toString()).setScale(1, RoundingMode.DOWN).floatValue()));
                } else {
                    airCompressor.setNeGaTive("0.0");
                }
                if (entries.get("sPraying") != null && !"".equals(entries.get("sPraying"))) {
                    airCompressor.setSPraying(decimalFormat.format(new BigDecimal(entries.get("sPraying").toString()).setScale(1, RoundingMode.DOWN).floatValue()));
                } else {
                    airCompressor.setSPraying("0.0");
                }
                if (entries.get("motorSpeed") != null && !"".equals(entries.get("motorSpeed"))) {
                    airCompressor.setMotorSpeed(decimalFormat.format(new BigDecimal(entries.get("motorSpeed").toString()).setScale(1, RoundingMode.DOWN).floatValue()));
                } else {
                    airCompressor.setMotorSpeed("0.0");
                }

            } else {
                airCompressor.setMotorSpeed("0.0");
                airCompressor.setSPraying("0.0");
                airCompressor.setNeGaTive("0.0");
            }
            //进行名称拼接
            String objId  = String.valueOf(((Map) deviceIdMap.get(e.getDeviceId())).get("objId"));
            Map<String, Object> map = (Map) objectMap.get(objId);
            String objIdName = "";
            while(true){
                objIdName = objIdName == "" ? map.get("name") + objIdName : map.get("name") + "-" + objIdName;
                if ("0".equals(map.get("parentId"))){
                    break;
                }
                map = (Map) objectMap.get(map.get("parentId"));
            }
            airCompressor.setObjName(objIdName);
            airCompressor.setDeviceId(e.getDeviceId());
            airCompressor.setName(e.getName());
            airCompressor.setAlias(e.getAlias());
            airCompressor.setDateTime(DateUtil.format(new DateTime(), "yyyy-MM-dd HH:mm:ss"));
            airCompressors.add(airCompressor);
        });
        return airCompressors;
    }


    public List<DehumidifierVO> dehumidifierTree(Integer deviceType) {
        //key:除湿机房  value:属性值
        HashMap<String, List<DehumidifierVO.DehumidifierParameter>> hashMap = new HashMap<>();
        //找出所有除湿机类型的设备
        List<Equipment> equipmentList = equipmentMapper.selectEquipmentByType(deviceType);
        if (equipmentList != null && equipmentList.size() > 0) {
            ArrayList<DehumidifierVO> attributesArrayList = new ArrayList<>();
            equipmentList.stream().forEach(equipment -> {
                //有附加属性
                if (equipment.getAdditionalAttribute() != null && !"".equals(equipment.getAdditionalAttribute())) {
                    String additionalAttribute = equipment.getAdditionalAttribute();
                    List<DehumidifierVO.AdditionalAttributes> additionalAttributes = JSONArray.parseArray(additionalAttribute, DehumidifierVO.AdditionalAttributes.class);
                    //去掉RoomLocation为null的对象
                    List<DehumidifierVO.AdditionalAttributes> collect = additionalAttributes.stream().filter(item -> item.getRoomLocation() != null).collect(Collectors.toList());
                    if (collect != null && collect.size() > 0) {
                        //有附加属性且有除湿机房的请况
                        DehumidifierVO.AdditionalAttributes attributes = collect.get(0);
                        if (hashMap.containsKey(attributes.getRoomLocation())) {//hashmap中有这个key
                            List<DehumidifierVO.DehumidifierParameter> list = hashMap.get(attributes.roomLocation);
                            //                        DehumidifierVO.DehumidifierParameter parameter = new DehumidifierVO.DehumidifierParameter();
                            //                        parameter.setDeviceId(equipment.getDeviceId());
                            //从Redis中获取数据，并构造对象返回
                            DehumidifierVO.DehumidifierParameter parameter = null;
                            try {
                                parameter = getData(equipment);
                            } catch (Exception e) {
                                throw new RuntimeException(e);
                            }
                            if (attributes.getServiceArea() != null) {
                                parameter.setServiceArea(attributes.getServiceArea());
                            }
                            list.add(parameter);
                            hashMap.put(attributes.getRoomLocation(), list);
                        } else {//hashmap中没有这个key
                            //从Redis中获取数据，并构造对象返回
                            DehumidifierVO.DehumidifierParameter parameter = null;
                            try {
                                parameter = getData(equipment);
                            } catch (Exception e) {
                                throw new RuntimeException(e);
                            }
                            //                        DehumidifierVO.DehumidifierParameter parameter = new DehumidifierVO.DehumidifierParameter();
                            //                        parameter.setDeviceId(equipment.getDeviceId());
                            if (parameter != null && attributes.getServiceArea() != null) {
                                parameter.setServiceArea(attributes.getServiceArea());
                            }
                            List<DehumidifierVO.DehumidifierParameter> list = new ArrayList<>();
                            list.add(parameter);
                            hashMap.put(attributes.roomLocation, list);
                        }
                    } else {//有附加属性但是没有除湿机房的情况
                        //根据设备id查询楼宇名称
                        String objName = getaVoid(equipment);
                        if (objName != null) {
                            if (hashMap.containsKey(objName)) {//hashmap中有这个key
                                List<DehumidifierVO.DehumidifierParameter> list = hashMap.get(objName);
                                //                            DehumidifierVO.DehumidifierParameter parameter = new DehumidifierVO.DehumidifierParameter();
                                //                            parameter.setDeviceId(equipment.getDeviceId());
                                //从Redis中获取数据，并构造对象返回
                                DehumidifierVO.DehumidifierParameter parameter = null;
                                try {
                                    parameter = getData(equipment);
                                } catch (Exception e) {
                                    throw new RuntimeException(e);
                                }
                                List<DehumidifierVO.AdditionalAttributes> attributes = additionalAttributes.stream().filter(item -> item.getServiceArea() != null).collect(Collectors.toList());
                                if (attributes != null && attributes.get(0).getServiceArea() != null && !"".equals(attributes.get(0).getServiceArea())) {
                                    if (parameter != null) {
                                        parameter.setServiceArea(attributes.get(0).getServiceArea());
                                    } else {
                                        parameter = new DehumidifierVO.DehumidifierParameter();
                                        parameter.setServiceArea(attributes.get(0).getServiceArea());
                                    }
                                }
                                list.add(parameter);
                                hashMap.put(objName, list);
                            } else {//hashmap中没有这个key
                                //                            DehumidifierVO.DehumidifierParameter parameter = new DehumidifierVO.DehumidifierParameter();
                                //                            parameter.setDeviceId(equipment.getDeviceId());
                                //从Redis中获取数据，并构造对象返回
                                DehumidifierVO.DehumidifierParameter parameter = null;
                                try {
                                    parameter = getData(equipment);
                                } catch (Exception e) {
                                    throw new RuntimeException(e);
                                }
                                List<DehumidifierVO.AdditionalAttributes> attributes = additionalAttributes.stream().filter(item -> item.getServiceArea() != null).collect(Collectors.toList());
                                if (attributes != null && attributes.size() > 0 && attributes.get(0).getServiceArea() != null && !"".equals(attributes.get(0).getServiceArea())) {
                                    if (parameter != null) {
                                        parameter.setServiceArea(attributes.get(0).getServiceArea());
                                    } else {
                                        parameter = new DehumidifierVO.DehumidifierParameter();
                                        parameter.setServiceArea(attributes.get(0).getServiceArea());
                                    }
                                }
                                List<DehumidifierVO.DehumidifierParameter> list = new ArrayList<>();
                                list.add(parameter);
                                hashMap.put(objName, list);
                            }
                        }
                    }
                } else {
                    //没有附加属性
                    //根据设备id查询楼宇名称
                    String objName = getaVoid(equipment);
                    if (objName != null) {
                        if (hashMap.containsKey(objName)) {//hashmap中有这个key
                            List<DehumidifierVO.DehumidifierParameter> list = hashMap.get(objName);
                            //                        DehumidifierVO.DehumidifierParameter parameter = new DehumidifierVO.DehumidifierParameter();
                            //                        parameter.setDeviceId(equipment.getDeviceId());
                            DehumidifierVO.DehumidifierParameter parameter = null;
                            try {
                                parameter = getData(equipment);
                            } catch (Exception e) {
                                throw new RuntimeException(e);
                            }
                            if (parameter != null) {
                                list.add(parameter);
                            }
                            hashMap.put(objName, list);
                        } else {//hashmap中没有这个key
                            //                        DehumidifierVO.DehumidifierParameter parameter = new DehumidifierVO.DehumidifierParameter();
                            //                        parameter.setDeviceId(equipment.getDeviceId());
                            DehumidifierVO.DehumidifierParameter parameter = null;
                            try {
                                parameter = getData(equipment);
                            } catch (Exception e) {
                                throw new RuntimeException(e);
                            }
                            List<DehumidifierVO.DehumidifierParameter> list = null;
                            if (parameter != null) {
                                list = new ArrayList<>();
                                list.add(parameter);
                            }
                            hashMap.put(objName, list);
                        }
                    }
                }

            });
            //获取hashmap中所有的key
            for (String key : hashMap.keySet()) {
                DehumidifierVO dehumidifierVO = new DehumidifierVO();
                dehumidifierVO.setDehumidifierRoom(key);
                dehumidifierVO.setDehumidifierParameterList(hashMap.get(key));
                attributesArrayList.add(dehumidifierVO);
            }

            return attributesArrayList;
        } else {
            return null;
        }
    }

    /**
     * 根据设备id查询楼层名字
     *
     * @param equipment
     * @return
     */
    @Nullable
    private String getaVoid(Equipment equipment) {
        return objMoudelMapper.getObjName(equipment.getDeviceId());
    }

    /**
     * 根据设备id去Redis中获取实时数据
     *
     * @param equipment
     * @return
     */
    private DehumidifierVO.DehumidifierParameter getData(Equipment equipment) throws NoSuchFieldException, IllegalAccessException {
        Map entries = redisTemplate.opsForHash().entries(equipment.getDeviceId());
        DehumidifierVO.DehumidifierParameter parameter = new DehumidifierVO.DehumidifierParameter();
        parameter.setDeviceId(equipment.getDeviceId());
        parameter.setDeviceName(equipment.getName());
        if (entries != null && entries.size() > 0) {
            //设备状态
            if (entries.containsKey("type") && entries.get("type") != null && !"".equals(entries.get("type"))) {
                parameter.setType((entries.get("type").toString()));
            }
            if (parameter.getType() != null) {
                if (parameter.getType().equals("正常")) {
                    //通过反射给属性复制
                    Class<? extends DehumidifierVO.DehumidifierParameter> parameterClass = parameter.getClass();
                    Field[] declaredFields = parameterClass.getDeclaredFields();

                    if (declaredFields != null && declaredFields.length > 0) {
                        for (Field field : declaredFields) {
                            //获取属性名 如supplyAirTemperature
                            String name = field.getName();
                            if (entries.containsKey(name) && field.getGenericType().toString().endsWith("float")) { //如果Redis中保存了这个属性并且这个属性是float类型，就赋值
                                Field declaredField = parameterClass.getDeclaredField(name);
                                declaredField.setAccessible(true);
                                float parseFloat = Float.parseFloat(entries.get(name).toString());
                                declaredField.set(parameter, parseFloat);
                            }
                        }
                    }
                }
            } else {
                parameter.setType("离线");
            }

        } else {
            parameter.setType("离线");
        }
        return parameter;
    }
}
